home *** CD-ROM | disk | FTP | other *** search
- #include "lisp.hpp"
- #include "lisp_gc.hpp"
- #include "compiled.hpp"
- #include "objects.hpp"
- #include "level.hpp"
- #include "game.hpp"
- #include "jrand.hpp"
- #include "clisp.hpp"
- #include "ant.hpp"
- #include "key_cfg.hpp"
-
- enum { point_angle, fire_delay1 };
-
- #define SHOTGUN 10
- #define GRENADE 2
- #define ROCKET 3
- #define PLASMA 4
- #define FIREBOMB 5
- #define DFRIS 6
- #define LSABER 7
-
- extern int registered;
-
- signed char small_fire_off[24*2]= // x & y offset from character to end of gun.
- { 17,20, // 1
- 17,23, // 2
- 17,28,
- 15,33,
- 11,39, // 5
- 7,43,
- -3,44, // 7
- -10,42,
- -16,39,
- -20,34,
- -20,28,
- -20,25,
- -19,20,
- -19,16,
- -16,14,
- -14,11,
- -11,9,
- -7,8,
- -3,8,
- 2,8,
- 6,9,
- 10,10,
- 14,13,
- 16,15 };
-
- signed char large_fire_off[24*2]=
- { 18,25,
- 17,30,
- 15,34,
- 14,36,
- 10,39,
- 7,41,
- 4,42,
- -3,41,
- -8,39,
- -11,37,
- -14,33,
- -16,30,
- -18,25,
- -17,21,
- -14,17,
- -11,15,
- -7,13,
- -4,12,
- 3,12,
- 9,12,
- 12,15,
- 14,16,
- 15,18,
- 16,21 };
-
-
- enum { in_climbing_area,
- disable_top_draw,
- just_hit,
- ship_pan_x,
- special_power,
- used_special_power,
- last1_x, last1_y,
- last2_x, last2_y,
- has_saved_this_level,
- r_ramp, g_ramp, b_ramp,
- is_teleporting,
- just_fired};
-
-
- enum { sgb_speed,
- sgb_angle,
- sgb_lastx,
- sgb_lasty,
- sgb_bright_color,
- sgb_medium_color,
- sgb_lifetime };
-
- enum { NO_POWER,
- FAST_POWER,
- FLY_POWER,
- SNEAKY_POWER,
- HEALTH_POWER } ;
-
- enum { top_point_angle,
- top_fire_delay1,
- top_just_fired };
-
- inline int angle_diff(int a1, int a2)
- {
- if (a1<a2)
- { if ((a2-a1)<180)
- return a2-a1;
- else return 360-a2+a1;
- } else
- {
- if ((a1-a2)<180)
- return a1-a2;
- else return 360-a1+a2;
- }
- return 0;
- }
-
- extern char *symbol_str(char *name);
-
- void *top_ai()
- {
- game_object *o=current_object;
- if (o->total_objects()) // make sure we are linked to the main character
- {
- game_object *q=o->get_object(0);
-
- view *v=q->controller();
- if (v)
- {
- if (!v->freeze_time)
- {
- o->direction=1; // always face right
-
- if (q->direction<0)
- q->x+=4;
- int i;
- signed char *fire_off=o->otype==S_DFRIS_TOP ? large_fire_off :
- (o->otype==S_ROCKET_TOP ? large_fire_off :
- (o->otype==S_BFG_TOP ? large_fire_off : small_fire_off));
- signed char *f=fire_off,*fb;
- int best_diff=200,best_num;
- int iy=f[1],ix=f[6*2];
-
- int best_angle=lisp_atan2(q->y-iy-v->pointer_y,v->pointer_x-q->x-ix);
- for (i=0;i<24;i++,f+=2) // check all the angles to see which would best fit animation wise
- {
- int this_angle=lisp_atan2(f[1]-iy,f[0]-ix);
- int this_diff=angle_diff(this_angle,best_angle);
- if (this_diff<best_diff)
- {
- best_diff=this_diff;
- best_num=i;
- fb=f;
- }
- }
-
-
- // if the pointer is too close to the player go with the angle shown, not the angle through the pointer
- if (abs(q->y-fb[1]-v->pointer_y)<45 & abs(v->pointer_x-q->x+fb[0])<40)
- o->lvars[point_angle]=lisp_atan2(fb[1]-iy,fb[0]-ix);
- else
- o->lvars[point_angle]=lisp_atan2(q->y-fb[1]-v->pointer_y,v->pointer_x-(q->x+fb[0]));
-
-
- if (q->direction<0)
- q->x-=4;
-
- o->x=q->x;
- o->y=q->y+29-q->picture()->height();
-
- rand_on+=o->lvars[point_angle];
- o->current_frame=best_num;
-
-
- if (o->lvars[fire_delay1])
- o->lvars[fire_delay1]--;
-
- o->otype=weapon_types[v->current_weapon]; // switch to correct top part
- }
- }
- }
- return true_symbol;
- }
-
-
- int player_fire_weapon(game_object *o, int type, game_object *target, int angle, signed char *fire_off)
- {
-
- if (!o->total_objects()) return 0;
- game_object *other=o->get_object(0);
- int ox=other->x,oy=other->y;
- if (other->direction<0) other->x+=4;
-
- int firex=other->x+fire_off[o->current_frame*2];
- int firey=other->y-fire_off[o->current_frame*2+1];
-
-
-
- // fire try to move up to gun level
-
- long x2=o->x,y2=firey;
- // current_level->foreground_intersect(other->x,other->y,x2,y2); // find first location we can actuall "see"
- // current_level->all_boundary_setback(o,other->x,other->y,x2,y2); // to make we don't fire through walls
- other->y=y2;
-
- if (other->y==firey) // now try to move out to end of gun if we were not blocked above
- {
- x2=firex;
- current_level->foreground_intersect(other->x,other->y,x2,y2); // find first location we can actuall "see"
- current_level->all_boundary_setback(other,other->x,other->y,x2,y2); // to make we don't fire through walls
- o->x=x2;
- }
-
- void *list=NULL;
- p_ref r1(list);
- push_onto_list(new_lisp_pointer(target),list);
- push_onto_list(new_lisp_number(angle),list);
- push_onto_list(new_lisp_number(y2),list);
- push_onto_list(new_lisp_number(x2),list);
- push_onto_list(new_lisp_number(type),list);
- push_onto_list(new_lisp_pointer(o->get_object(0)),list);
- eval_function((lisp_symbol *)l_fire_object,list);
- o->lvars[top_just_fired]=1;
- other->lvars[just_fired]=1;
- other->x=ox;
- other->y=oy;
-
- return 1;
- }
-
-
-
- void *laser_ufun(void *args)
- {
- game_object *o=current_object;
- p_ref r1(args);
- void *signal=CAR(args); args=CDR(args);
- void *ret=NULL;
-
- if (signal==l_FIRE)
- {
- if (!o->lvars[fire_delay1]) // make sur we are not waiting of previous fire
- {
- long value=lnumber_value(eval(CAR(args)));
- if (value) // do we have ammo ?
- {
- o->lvars[fire_delay1]=3;
- if (player_fire_weapon(o,SHOTGUN,NULL,o->lvars[point_angle],small_fire_off))
- ret=new_lisp_number(-1);
- else ret=new_lisp_number(0);
- } else
- {
- o->lvars[fire_delay1]=5; // no ammo, set large fire delay for next shot
- player_fire_weapon(o,SHOTGUN,NULL,o->lvars[point_angle],small_fire_off);
- ret=new_lisp_number(0);
- }
- } else ret=new_lisp_number(0); // can't fire yet, return 0 ammo subtract
- }
- return ret;
- }
-
-
- static int ammo_type(int otype)
- {
- if (otype==S_GRENADE_TOP)
- return GRENADE;
- else if (otype==S_FIREBOMB_TOP)
- return FIREBOMB;
- else if (otype==S_DFRIS_TOP)
- return DFRIS;
- else return SHOTGUN;
- }
-
-
- void *top_ufun(void *args) // generic top character ai GRENADE && FIREBOMB
- {
- game_object *o=current_object;
- p_ref r1(args);
- void *signal=CAR(args); args=CDR(args);
- void *ret=NULL;
-
- if (signal==l_FIRE)
- {
- if (!o->lvars[fire_delay1]) // make sur we are not waiting of previous fire
- {
- long value=lnumber_value(eval(CAR(args)));
- if (value) // do we have ammo ?
- {
- o->lvars[fire_delay1]=6;
- if (player_fire_weapon(o,ammo_type(o->otype),NULL,o->lvars[point_angle],
- o->otype==DFRIS ? large_fire_off : small_fire_off ))
- ret=new_lisp_number(-1);
- else ret=new_lisp_number(0);
- } else ret=new_lisp_number(0);
- } else ret=new_lisp_number(0); // can't fire yet, return 0 ammo subtract
- }
- return ret;
- }
-
- static int climb_handler(game_object *, int xm, int ym, int but);
-
- void *plaser_ufun(void *args)
- {
- game_object *o=current_object;
- p_ref r1(args);
- void *signal=CAR(args); args=CDR(args);
- void *ret=NULL;
-
- if (signal==l_FIRE)
- {
- if (!o->lvars[fire_delay1]) // make sur we are not waiting of previous fire
- {
- long value=lnumber_value(eval(CAR(args)));
- if (value) // do we have ammo ?
- {
- o->lvars[fire_delay1]=2;
- if (player_fire_weapon(o,PLASMA,NULL,o->lvars[point_angle],small_fire_off))
- ret=new_lisp_number(-1);
- else ret=new_lisp_number(0);
- } else ret=new_lisp_number(0);
- } else ret=new_lisp_number(0); // can't fire yet, return 0 ammo subtract
- }
- return ret;
- }
-
- void *lsaber_ufun(void *args)
- {
- game_object *o=current_object;
- p_ref r1(args);
- void *signal=CAR(args); args=CDR(args);
- void *ret=NULL;
-
- if (signal==l_FIRE)
- {
- if (!o->lvars[fire_delay1]) // make sur we are not waiting of previous fire
- {
- long value=lnumber_value(eval(CAR(args)));
- if (value) // do we have ammo ?
- {
- o->lvars[fire_delay1]=1;
- if (player_fire_weapon(o,LSABER,NULL,o->lvars[point_angle]+(current_level->tick_counter()&7)-8,
- small_fire_off))
- ret=new_lisp_number(-1);
- else ret=new_lisp_number(0);
- } else ret=new_lisp_number(0);
- } else ret=new_lisp_number(0); // can't fire yet, return 0 ammo subtract
- }
- return ret;
- }
-
-
-
- void *player_rocket_ufun(void *args)
- {
- game_object *o=current_object;
- p_ref r1(args);
- void *signal=CAR(args); args=CDR(args);
- void *ret=NULL;
- int xd,yd,cl=0xfffffff,d;
- if (signal==l_FIRE)
- {
- if (!o->lvars[fire_delay1]) // make sur we are not waiting of previous fire
- {
- long value=lnumber_value(eval(CAR(args)));
- if (value) // do we have ammo ?
- {
- o->lvars[fire_delay1]=6;
- game_object *target=NULL,*p,*bot=o->total_objects() ? o->get_object(0) : 0;
- if (bad_guy_array)
- {
- game_object *other=current_object->total_objects() ? current_object->get_object(0) : 0;
- for (p=current_level->first_active_object();p;p=p->next_active)
- {
- xd=abs(p->x-o->x);
- yd=abs(p->y-o->y);
- if (xd<160 && yd<130 && bad_guy_array[p->otype] && p!=other)
- {
- if (p->targetable() &&
- !(p->otype==S_ROCKET && p->total_objects() && p->get_object(0)==bot)) // don't track onto own missles
- {
- d=xd*xd+yd*yd;
- if (d<cl)
- {
- cl=d;
- target=p;
- }
- }
- }
- }
- }
- if (player_fire_weapon(o,ROCKET,target,o->lvars[point_angle],large_fire_off))
- ret=new_lisp_number(-1);
- else ret=new_lisp_number(0);
-
- } else ret=new_lisp_number(0);
- } else ret=new_lisp_number(0); // can't fire yet, return 0 ammo subtract
- }
- return ret;
- }
-
- static int player_move(game_object *o, int xm, int ym, int but)
- {
- if (!o->lvars[in_climbing_area])
- {
- if (o->state==S_climbing)
- {
- o->set_gravity(1);
- o->set_state(run_jump_fall);
- }
- o->next_picture();
- return o->mover(xm,ym,but);
- } else return climb_handler(o,xm,ym,but);
-
- }
-
-
- static void undo_special_power(game_object *o)
- {
- switch (o->lvars[special_power])
- {
- case SNEAKY_POWER :
- {
- if (o->lvars[used_special_power]>0)
- o->lvars[used_special_power]--;
- } break;
- case FAST_POWER :
- {
- o->lvars[used_special_power]=0;
- } break;
- }
- }
-
- static void do_special_power(game_object *o, int xm, int ym, int but, game_object *top)
- {
- switch (o->lvars[special_power])
- {
- case FLY_POWER :
- {
- if (registered)
- {
- game_object *cloud=create(S_CLOUD,o->x+o->direction*-10,o->y+jrand()%5);
- if (current_level)
- current_level->add_object(cloud);
- o->set_state(run_jump);
- o->set_gravity(1);
- o->set_yacel(0);
- if (o->yvel()>0) o->set_yvel(o->yvel()/2);
- if (ym<0)
- o->set_yvel(o->yvel()-3);
- else
- o->set_yvel(o->yvel()-2);
- the_game->play_sound(S_FLY_SND,32,o->x,o->y);
- }
- } break;
- case FAST_POWER :
- {
- if ((current_level->tick_counter()%16)==0)
- the_game->play_sound(S_SPEED_SND,100,o->x,o->y);
-
- o->lvars[used_special_power]=1;
- o->lvars[last1_x]=o->x;
- o->lvars[last1_y]=o->y;
- long oyvel=o->yvel();
- int in=o->lvars[in_climbing_area];
- int ok;
-
-
- player_move(o,xm,ym,but);
- if (ym<0 && !oyvel && o->yvel()<0) // if they just jumped, make them go higher
- o->set_yvel(o->yvel()+o->yvel()/3);
- o->lvars[in_climbing_area]=in;
-
- o->lvars[last2_x]=o->x;
- o->lvars[last2_x]=o->y;
- } break;
- case SNEAKY_POWER :
- {
- if (registered)
- {
- if (o->lvars[used_special_power]<15)
- o->lvars[used_special_power]++;
- }
- } break;
- }
- }
-
- static int climb_off_handler(game_object *o)
- {
- if (o->next_picture())
- o->controller()->pan_y-=4;
- else
- {
- o->y-=28;
- o->controller()->pan_y+=28;
- o->controller()->last_y-=28;
- o->set_state(stopped);
- }
- return 0;
- }
-
-
- static int climb_on_handler(game_object *o)
- {
- if (o->next_picture())
- o->controller()->pan_y+=4;
- else
- o->set_state((character_state)S_climbing);
- return 0;
- }
-
- static int climb_handler(game_object *o, int xm, int ym, int but)
- {
- int yd=o->lvars[in_climbing_area]; // see how from the top we are
- o->lvars[in_climbing_area]=0; // set 0, ladders will set back to proper if still in area
- if (o->state==S_climb_off)
- climb_off_handler(o);
- else if (o->state==S_climb_on)
- climb_on_handler(o);
- else
- {
- if (o->state==S_climbing)
- {
- if (ym>0) // going down
- {
-
- if (o->current_frame==0) o->current_frame=9;
- o->current_frame--;
-
- /* if (o->lvars[special_power]==FAST_POWER)
- {
- long xv=0,yv=4;
- o->try_move(o->x,o->y,xv,yv,1);
- if (yv==4)
- o->y+=3;
- else
- {
- o->set_gravity(1);
- o->set_state(run_jump_fall);
- }
- }
- else */ o->y+=3;
-
-
- } else if (ym<0)
- {
- if (yd<32)
- o->set_state((character_state)S_climb_off);
- else
- {
- if (!o->next_picture()) o->set_state((character_state)S_climbing);
- o->y-=3;
- }
- }
- if (xm) // trying to get off the ladder, check to see if that's ok
- {
- long x2=0,y2=-20;
- o->try_move(o->x,o->y,x2,y2,3);
- if (y2==-20)
- {
- o->set_gravity(1);
- if (ym>=0)
- o->set_state(run_jump_fall);
- else
- { o->set_state(run_jump);
- o->set_yvel(get_ability(o->otype,jump_yvel));
- }
- }
- }
- } else if (ym>0 && yd<10)
- {
- o->y+=28;
- o->controller()->pan_y-=28;
- o->controller()->last_y+=28;
- o->set_state((character_state)S_climb_on);
- }
- else if (o->yvel()>=0 && (ym>0 || (ym<0 && yd>8)))
- {
- o->set_state((character_state)S_climbing);
- o->set_gravity(0);
- o->set_xvel(0);
- o->set_yvel(0);
- o->set_xacel(0);
- o->set_yacel(0);
- return 0;
- } else
- {
- o->next_picture();
- return o->mover(xm,ym,but);
- }
- }
- return 0;
- }
-
-
- void *cop_mover(int xm, int ym, int but)
- {
-
- int ret=0;
- game_object *o=current_object,*top;
- if (o->controller() && o->controller()->freeze_time)
- {
- o->controller()->freeze_time--;
- if (but || o->controller()->key_down(JK_SPACE) || o->controller()->key_down(JK_ENTER))
- o->controller()->freeze_time=0;
- }
- else
- {
- if (!o->total_objects()) // if no top create one
- {
- top=create(S_MGUN_TOP,o->x,o->y,0,0);
- current_level->add_object_after(top,o);
- o->add_object(top);
- top->add_object(o);
- } else top=o->get_object(0);
-
- if (o->yvel()>10)
- {
- o->set_yacel(0);
- o->set_yvel(o->yvel()-1); // terminal velocity
- }
-
- if (o->aistate()==0) // just started, wait for button
- {
- o->set_aistate(1);
- } else if (o->aistate()==1) // normal play
- {
- if (o->hp()==0)
- {
- o->set_aistate(2); // go to deing state
- o->set_state(dead);
- }
- else
- {
- if (o->hp()<40 && (current_level->tick_counter()%16)==0) // if low on health play heart beat
- the_game->play_sound(S_LOW_HEALTH_SND,127,o->x,o->y);
- else if (o->hp()<15 && (current_level->tick_counter()%8)==0) // if low on health play heart beat
- the_game->play_sound(S_LOW_HEALTH_SND,127,o->x,o->y);
- else if (o->hp()<7 && (current_level->tick_counter()%4)==0) // if low on health play heart beat
- the_game->play_sound(S_LOW_HEALTH_SND,127,o->x,o->y);
-
- if (but&1)
- do_special_power(o,xm,ym,but,top);
- else
- undo_special_power(o);
- ret=player_move(o,xm,ym,but);
- top->x=o->x;
- top->y=o->y+29-top->picture()->height();
-
- if ((but&2) && !o->lvars[is_teleporting] && o->state!=S_climbing && o->state!=S_climb_off)
- {
- void *args=NULL;
- p_ref r1(args);
- view *v=o->controller();
-
- push_onto_list(new_lisp_number(v->weapon_total(v->current_weapon)),args);
- push_onto_list(l_FIRE,args);
-
- current_object=top;
- void *ret=eval_function((lisp_symbol *)figures[top->otype]->get_fun(OFUN_USER_FUN),args);
- current_object=o;
- v->add_ammo(v->current_weapon,lnumber_value(ret));
- }
- }
- } else if (o->aistate()==3)
- {
- if (!o->controller() || o->controller()->key_down(JK_SPACE))
- {
- int old_kills=o->controller()->kills; // this i s bit of a hack, save the kills
- eval_function((lisp_symbol *)l_restart_player,NULL); // call teh user function to reset the player
- o->controller()->reset_player();
- if (player_list->next)
- o->controller()->kills=old_kills; // if a multiplayer game restore their kills
- o->set_aistate(0);
- } else if (o->controller() && o->controller()->local_player())
- the_game->show_help(symbol_str("space_cont"));
-
- } else o->set_aistate(o->aistate()+1);
- }
-
- return new_lisp_number(ret);
- }
-
-
-
- void *ladder_ai()
- {
- view *f=player_list;
- game_object *o=current_object;
- if (o->total_objects())
- {
- game_object *other=o->get_object(0);
- for (;f;f=f->next)
- {
- int mex=f->focus->x;
- int mey=f->focus->y;
-
- if (o->x<=mex && o->y<=mey && other->x>=mex && other->y>=mey)
- {
- if (f->focus->state==S_climbing)
- f->focus->x=(o->x+other->x)/2;
- f->focus->lvars[in_climbing_area]=mey-o->y;
- }
- }
- }
- return true_symbol;
- }
-
-
-
- void *player_draw(int just_fired_var, int num)
- {
- game_object *o=current_object;
- if (num==0)
- {
- if (o->lvars[just_fired_var])
- {
- o->draw_tint(S_bright_tint);
- o->lvars[just_fired_var]=0;
- } else
- o->drawer();
- }
- else
- {
- if (o->lvars[just_fired_var])
- {
- o->draw_double_tint(lnumber_value(lget_array_element(symbol_value(l_player_tints),num)),S_bright_tint);
- o->lvars[just_fired_var]=0;
- } else
- o->draw_tint(lnumber_value(lget_array_element(symbol_value(l_player_tints),num)));
- }
- return NULL;
- }
-
-
- void *top_draw()
- {
- game_object *o=current_object;
- if (o->total_objects())
- {
- game_object *bot=o->get_object(0);
- if (bot->state==stopped || bot->state==running ||
- bot->state==run_jump || bot->state==run_jump_fall ||
- bot->state==end_run_jump)
- {
- int oldy=o->y;
- o->x=bot->x;
- if (bot->direction<0)
- o->x+=4;
- o->y=bot->y+29-bot->picture()->height();
-
- void *ret=NULL;
- p_ref r1(ret);
-
- push_onto_list(new_lisp_number(bot->controller()->player_number),ret);
-
- if (bot->lvars[special_power]==SNEAKY_POWER)
- {
- if (bot->lvars[used_special_power]==0)
- player_draw(top_just_fired,bot->controller()->player_number);
- else if (bot->lvars[used_special_power]<15)
- o->draw_trans(bot->lvars[used_special_power],16);
- else
- o->draw_predator();
- } else
- eval_function((lisp_symbol *)l_player_draw,ret);
-
- o->y=oldy;
- if (bot->direction<0)
- o->x-=4;
- }
- }
- return NULL;
- }
-
-
-
- void *bottom_draw()
- {
- game_object *o=current_object;
-
- if (o->lvars[r_ramp] || o->lvars[g_ramp] || o->lvars[b_ramp])
- {
- int r=o->lvars[r_ramp];
- if (r>7) r-=7;
- else r=0;
- o->lvars[r_ramp]=r;
-
- int g=o->lvars[g_ramp];
- if (g>7) g-=7;
- else g=0;
- o->lvars[g_ramp]=g;
-
- int b=o->lvars[b_ramp];
- if (b>7) b-=7;
- else b=0;
- o->lvars[b_ramp]=b;
-
- palette *p=pal->copy();
- uchar *addr=(uchar *)p->addr();
- int ra,ga,ba;
-
- for (int i=0;i<256;i++)
- {
- ra=(int)*addr+r; if (ra>255) ra=255; else if (ra<0) r=0; *addr=(uchar)ra; addr++;
- ga=(int)*addr+g; if (ga>255) ga=255; else if (ga<0) g=0; *addr=(uchar)ga; addr++;
- ba=(int)*addr+b; if (ba>255) ba=255; else if (ba<0) b=0; *addr=(uchar)ba; addr++;
- }
- p->load();
- delete p;
- }
-
- if (o->aistate()>0)
- {
- switch (o->lvars[special_power])
- {
- case NO_POWER :
- { player_draw(just_fired,o->controller()->player_number); } break;
-
- case HEALTH_POWER :
- {
- player_draw(just_fired,o->controller()->player_number);
- if (o->controller() && o->controller()->local_player())
- cash.img(S_health_image)->put_image(screen,o->controller()->cx2-20,
- o->controller()->cy1+5,1);
- } break;
- case FAST_POWER :
- {
- eval_function((lisp_symbol *)l_draw_fast,NULL);
- int old_state=o->state;
- switch (o->state)
- {
- case stopped : o->state=(character_state)S_fast_stopped; break;
- case running : o->state=(character_state)S_fast_running; break;
- case start_run_jump : o->state=(character_state)S_fast_start_run_jump; break;
- case run_jump : o->state=(character_state)S_fast_run_jump; break;
- case run_jump_fall : o->state=(character_state)S_fast_run_jump_fall; break;
- case end_run_jump : o->state=(character_state)S_fast_end_run_jump; break;
- }
-
- player_draw(just_fired,o->controller()->player_number);
- o->state=(character_state)old_state;
- if (o->controller() && o->controller()->local_player())
- cash.img(S_fast_image)->put_image(screen,o->controller()->cx2-20,
- o->controller()->cy1+5,1);
- } break;
- case FLY_POWER :
- {
- int old_state=o->state;
- switch (o->state)
- {
- case stopped : o->state=(character_state)S_fly_stopped; break;
- case running : o->state=(character_state)S_fly_running; break;
- case start_run_jump : o->state=(character_state)S_fly_start_run_jump; break;
- case run_jump : o->state=(character_state)S_fly_run_jump; break;
- case run_jump_fall : o->state=(character_state)S_fly_run_jump_fall; break;
- case end_run_jump : o->state=(character_state)S_fly_end_run_jump; break;
- }
-
- player_draw(just_fired,o->controller()->player_number);
- o->state=(character_state)old_state;
-
- if (o->controller() && o->controller()->local_player())
- cash.img(S_fly_image)->put_image(screen,o->controller()->cx2-20,
- o->controller()->cy1+5,1);
- } break;
- case SNEAKY_POWER :
- {
- if (o->lvars[used_special_power]==0)
- player_draw(just_fired,o->controller()->player_number);
- else if (o->lvars[used_special_power]<15)
- o->draw_trans(o->lvars[used_special_power],16);
- else
- o->draw_predator();
-
- if (o->controller() && o->controller()->local_player())
- cash.img(S_sneaky_image)->put_image(screen,o->controller()->cx2-20,
- o->controller()->cy1+5,1);
- } break;
- }
- }
- return NULL;
- }
-
-
-
- void *sgun_ai()
- {
- game_object *o=current_object;
-
- if (o->lvars[sgb_lifetime]==0)
- return NULL;
- o->lvars[sgb_lifetime]--;
-
- o->lvars[sgb_lastx]=o->x;
- o->lvars[sgb_lasty]=o->y;
- o->lvars[sgb_speed]=o->lvars[sgb_speed]*6/5;
-
- long ang=o->lvars[sgb_angle];
- long mag=o->lvars[sgb_speed];
-
- long xvel=(lisp_cos(ang))*(mag);
- current_object->set_xvel(xvel>>16);
- current_object->set_fxvel((xvel&0xffff)>>8);
- long yvel=-(lisp_sin(ang))*(mag);
- current_object->set_yvel(yvel>>16);
- current_object->set_fyvel((yvel&0xffff)>>8);
-
-
- int whit=0;
- game_object *who=o->bmove(whit, o->total_objects() ? o->get_object(0) : 0);
-
- if (whit || (who && figures[who->otype]->get_cflag(CFLAG_UNACTIVE_SHIELD) && who->total_objects() &&
- who->get_object(0)->aistate()==0))
- {
- o->lvars[sgb_lifetime]=0;
- game_object *n=create(S_EXPLODE5,o->x+jrand()%4,o->y+jrand()%4);
- current_level->add_object(n);
- } else if (who && figures[who->otype]->get_cflag(CFLAG_HURTABLE))
- {
- o->lvars[sgb_lifetime]=0;
- game_object *n=create(S_EXPLODE3,o->x+jrand()%4,o->y+jrand()%4);
- current_level->add_object(n);
- who->do_damage(5,o,o->x,o->y,(lisp_cos(ang)*10)>>16,(lisp_sin(ang)*10)>>16);
- }
- return true_symbol;
- }
-
-
-
- void *mover_ai()
- {
- game_object *o=current_object;
- if (o->total_objects()==2)
- {
- if (o->aistate()<2)
- {
- game_object *obj=o->get_object(1);
- o->remove_object(obj);
- game_object *d=o->get_object(0);
- d->add_object(obj);
- d->set_aistate(d->aitype());
- } else
- {
- o->set_aistate(o->aistate()-1);
- game_object *d=o->get_object(0);
- game_object *obj=o->get_object(1);
-
- obj->x=d->x-(d->x-o->x)*o->aistate()/o->aitype();
- obj->y=d->y-(d->y-o->y)*o->aistate()/o->aitype();
- }
- }
- return true_symbol;
- }
-
-
- void *respawn_ai()
- {
- game_object *o=current_object;
- int x=o->total_objects();
- if (x)
- {
- game_object *last=o->get_object(x-1);
- if (last->x==o->x && last->y==o->y)
- {
- if (last->fade_count())
- last->set_fade_count(last->fade_count()-1);
- o->set_aistate_time(0);
- } else if (o->aistate_time()>o->xvel())
- {
- int type=o->get_object(jrandom(x))->otype;
- game_object *n=create(type,o->x,o->y);
- current_level->add_object(n);
- o->add_object(n);
- n->set_fade_count(15);
- o->set_aistate_time(0);
- }
- }
- return true_symbol;
- }
-
- static int compare_players(const void *a, const void *b)
- {
- if ( ((view **)a)[0]->kills > ((view **)b)[0]->kills)
- return -1;
- else if ( ((view **)a)[0]->kills < ((view **)b)[0]->kills)
- return 1;
- else if (((view **)a)[0]->player_number > ((view **)b)[0]->player_number)
- return -1;
- else if (((view **)a)[0]->player_number < ((view **)b)[0]->player_number)
- return 1;
- else return 0;
- }
-
- void *score_draw()
- {
- view *sorted_players[16],*local=NULL;
- int tp=0;
- view *f=player_list;
- for (;f;f=f->next)
- {
- sorted_players[tp]=f;
- tp++;
- if (f->local_player()) local=f;
- }
-
- JCFont *fnt=eh->frame_font();
- if (local)
- {
- qsort(sorted_players,tp,sizeof(view *),compare_players);
-
- int x=local->cx1;
- int y=local->cy1;
- char msg[100];
-
- int i;
- for (i=0;i<tp;i++)
- {
- int color=lnumber_value(lget_array_element(symbol_value(l_player_text_color),sorted_players[i]->player_number));
- sprintf(msg,"%3d %s",sorted_players[i]->kills,sorted_players[i]->name);
- if (sorted_players[i]==local)
- strcat(msg," <<");
-
- fnt->put_string(screen,x,y,msg,color);
- y+=fnt->height();
- }
- }
- return NULL;
- }
-
-
- extern void fade_in(image *im, int steps);
- extern void fade_out(int steps);
-
- void *show_kills()
- {
- fade_out(8);
- eh->set_mouse_position(0,0);
- screen->clear();
-
- switch_mode(VMODE_640x480);
-
- int xp,yp;
- load_image_into_screen("art/frame.spe","end_level_screen",xp,yp);
-
- int x1=xp+342,y1=yp,x2=xp+639,y2=yp+294;
-
- JCFont *fnt=eh->font();
- fade_in(NULL,16);
-
- view *v=player_list; int tp=0,i;
- for (v=player_list;v;v=v->next) tp++;
-
- int y=(y1+y2)/2-(tp+2)*fnt->height()/2,x=x1+10;
- char *header_str=symbol_str("score_header");
- fnt->put_string(screen,x,y,header_str,eh->bright_color());
- y+=fnt->height();
-
- screen->wiget_bar(x,y+2,x+strlen(header_str)*fnt->width(),y+fnt->height()-3,
- eh->bright_color(),eh->medium_color(),eh->dark_color());
- y+=fnt->height();
- v=player_list;
- for (i=0;i<tp;i++)
- {
- enum { NAME_LEN=18 } ;
- int color=lnumber_value(lget_array_element(symbol_value(l_player_text_color),v->player_number));
- char max_name[NAME_LEN];
- strncpy(max_name,v->name,NAME_LEN-1);
- max_name[NAME_LEN-1]=0;
- char msg[100];
-
-
- sprintf(msg,"%-17s %3d %3d",max_name,v->kills,v->tkills+v->kills);
- fnt->put_string(screen,x,y,msg,color);
-
- y+=fnt->height();
- v=v->next;
- }
-
- eh->flush_screen();
- milli_wait(4000); // wait 4 seconds
-
- return NULL;
- }
-
-
-
- static void give_weapons(game_object *player, ushort otype)
- {
- view *v=player->controller();
- if (!v)
- {
- lbreak("object has no controller");
- exit(0);
- }
-
- int w_type=-1;
-
- if (otype==lnumber_value(symbol_value(l_MBULLET_ICON5)) || otype==lnumber_value(symbol_value(l_MBULLET_ICON20)))
- w_type=0;
-
- else if (otype==lnumber_value(symbol_value(l_GRENADE_ICON2)) || otype==lnumber_value(symbol_value(l_GRENADE_ICON10)))
- w_type=1;
-
- else if (otype==lnumber_value(symbol_value(l_ROCKET_ICON2)) || otype==lnumber_value(symbol_value(l_ROCKET_ICON5)))
- w_type=2;
-
- else if (otype==lnumber_value(symbol_value(l_FBOMB_ICON1)) || otype==lnumber_value(symbol_value(l_FBOMB_ICON5)))
- w_type=3;
-
- else if (otype==lnumber_value(symbol_value(l_PLASMA_ICON20)) || otype==lnumber_value(symbol_value(l_PLASMA_ICON50)))
- w_type=4;
-
- else if (otype==lnumber_value(symbol_value(l_LSABER_ICON50)) || otype==lnumber_value(symbol_value(l_LSABER_ICON100)))
- w_type=5;
-
- else if (otype==lnumber_value(symbol_value(l_DFRIS_ICON4)) || otype==lnumber_value(symbol_value(l_DFRIS_ICON10)))
- w_type=6;
-
-
- if (w_type!=-1)
- {
- if (!v->has_weapon(w_type))
- {
- v->give_weapon(w_type);
- if (symbol_value(l_change_on_pickup))
- v->current_weapon=w_type;
- }
-
-
-
- v->add_ammo(w_type,get_ability(otype,start_hp));
- }
- }
-
- void *weapon_icon_ai()
- {
- game_object *o=current_object;
- int try_fall=0;
-
-
- if (o->aistate()==0) // state 0 means we are stationary
- {
- if (o->total_objects()==0)
- {
- if ((jrand()%4)==0) // check to see if we should fall approx ever 4 ticks
- try_fall=1;
- } else if (o->get_object(0)->aistate()==1) // see if the object we are attached to is on
- try_fall=1;
- } else if (o->aistate()==1) // state 1 means we are currently falling
- try_fall=1;
-
-
- if (try_fall)
- {
- long x2=0,y2=10;
- game_object *who=o->try_move(o->x,o->y,x2,y2,3); // see if we can fall
-
-
- if (y2==0)
- {
- if (who)
- o->set_aistate(0); // we are on top of another object and we need to continue checking for falling
- else o->set_aistate(2); // we are on the ground, don't check for flaling anymore
- } else
- {
- o->y+=y2;
- o->set_aistate(1); // we are in flight, continue falling
- }
- }
-
-
- long x1,y1,x2,y2,xp1,yp1,xp2,yp2;
-
- game_object *player=current_level->attacker(current_object);
- player->picture_space(x1,y1,x2,y2);
- current_object->picture_space(xp1,yp1,xp2,yp2);
- if (!(xp1>x2 || xp2<x1 || yp1>y2 || yp2<y1))
- {
- the_game->play_sound(lnumber_value(symbol_value(l_ammo_snd)),127,o->x,o->y);
- give_weapons(player,o->otype);
- return NULL;
- }
-
- return true_symbol;
- }
-
-
-
- void *on_draw()
- {
- game_object *o=current_object;
- if (o->total_objects()==0 || o->get_object(0)->aistate() || (dev&EDIT_MODE))
- o->drawer();
- return 0;
- }
-
- void *tp2_ai()
- {
- enum { tp_waiting, tp_fading };
-
-
- game_object *o=current_object;
- if (o->total_objects())
- {
- if (o->aistate()==0) // wait for player to activate us
- {
- game_object *p=current_level->attacker(o);
-
- if (p->x>o->x-15 && p->x<o->x+15 && p->y>o->y-30 && p->y<o->y && p->controller()->y_suggestion>0)
- {
- o->add_object(p);
- o->set_aistate(tp_fading);
- the_game->play_sound(lnumber_value(symbol_value(l_TELEPORTER_SND)),127,o->x,o->y);
- o->set_state(running);
- }
- } else
- {
- game_object *p=o->get_object(1);
- if (o->next_picture())
- {
- p->x=o->x;
- p->y=o->y-16;
- int f=o->current_frame<16 ? o->current_frame : 15;
-
- p->set_fade_count(f);
- p->get_object(0)->set_fade_count(f);
- p->lvars[is_teleporting]=1;
- } else
- {
- p->x=o->get_object(0)->x;
- p->y=o->get_object(0)->y-16;
- p->lvars[is_teleporting]=0;
- p->set_fade_count(0);
- p->get_object(0)->set_fade_count(0);
- o->remove_object(p);
- o->set_aistate(tp_waiting);
- }
- }
- }
- return true_symbol;
- }
-
-
-
- void *push_char(void *args)
- {
- long xa=lnumber_value(CAR(args));
- long ya=lnumber_value(CAR(args));
-
- game_object *o=current_object;
- game_object *p=current_level->attacker(o);
-
- if (p->y<=o->y && abs(p->y-o->y)<ya && abs(p->x-o->x)<xa)
- {
- long amount;
- if (p->x>o->x)
- amount=xa-(p->x-o->x);
- else amount=(o->x-p->x)-xa;
- long yv=0;
- p->try_move(p->x,p->y,amount,yv,3);
- p->x+=amount;
- }
- return 0;
- }
-
- void *gun_draw()
- {
- game_object *o=current_object;
- o->draw_tint(lnumber_value(lget_array_element(symbol_value(l_gun_tints),o->aitype())));
- return 0;
- }
-
-
- void *ant_draw()
- {
- game_object *o=current_object;
- if (o->aitype()==0)
- o->drawer();
- else
- o->draw_tint(lnumber_value(lget_array_element(symbol_value(l_ant_tints),o->aitype())));
- return 0;
- }
-
- void *middle_draw()
- {
- game_object *o=current_object;
- int y=o->y;
- o->y+=o->picture()->height()/2;
- o->drawer();
- o->y=y;
- return 0;
- }
-
- void *exp_draw()
- {
- game_object *o=current_object;
- if (o->aitype()==0)
- middle_draw();
- return 0;
- }
-
- void *exp_ai()
- {
- game_object *o=current_object;
- if (o->aitype()==0)
- {
- if (o->next_picture())
- return true_symbol;
- else return 0;
- }
- else
- {
- o->set_aitype(o->aitype()-1);
- return true_symbol;
- }
- }
-